#!/usr/bin/env bash
# lj (c) 2012 Doj

method=
varssuccess=FAIL
ljdir=~/.lj/
ljrc=~/.ljrc
ljuri=http://www.livejournal.com/interface/flat
username=

checkljrc () {
    if [ $LJ_CONFIGURE_FILE ] ; then
        ljrc=$LJ_CONFIGURE_FILE
    fi
    if [ -e $ljrc ] ; then
        return 0
    fi
    echo "It seems you are running lj for the first time" 1>&2
    echo "Which file do you want to use for configuration lj?" 1>&2
    echo -n "(Default $ljrc): " 1>&2 && read ljrcuser
    if [ $ljrcuser ] ; then
        ljrc=$ljrcuser
    fi
    if [ -e $ljrc ] ; then
        echo -n "File $ljrc already exists. Override anyway? (y/n): " 1>&2 && read y
        if [ "$y" != "y" ]; then
            echo "lj: failed .ljrc creating" 1>&2
            return 1
        fi
    fi
    echo "# This file is just bash script                "  > $ljrc
    echo "# See head of main lj script for possible configuration "  > $ljrc
    echo ""                                                >> $ljrc
    echo "ljuri=$ljuri"                                    >> $ljrc
    if [ $ljrcuser ] ; then
        echo "Now put this line into your ~/.profile file: " 1>&2
        echo "  LJ_CONFIGURE_FILE=$ljrc; export LJ_CONFIGURE_FILE" 1>&2
        echo "And execute it before you call lj next time" 1>&2
        return 1
    fi
}

checkljrc || exit 1
. $ljrc

# not modifiable variables from .ljrc :D
clientversion=Bash-lj/0.1.1
useragent=bashlj

# script uses ljdir for saving private information about user
# we don't need to call this function when we don't need to read/write
# private information
# Usage: checkljdir || return 1
checkljdir () {
    if [ -e $ljdir ] ; then
        return 0
    fi
    echo "Which folder do you want to save authentification data?" 1>&2
    echo -n "(Default $ljdir): " 1>&2 && read ljdiruser
    if [ $ljdiruser ] ; then
        ljdir=$ljdiruser
    fi
    mkdir -p $ljdir
    chmod 700 $ljdir
    echo -n 1>&2
    echo chmod 700 $ljdir 1>&2
    echo "ljdir=$ljdir" >> $ljrc
}

# Usage: mk_range n
# prints sequence 1 2 3 ... n
mk_range () {
    local x=0
    while (( x++ < $1 )); do
        echo -n "$x "
    done
}

# urldecoding function for bash
# (c) 2003 GPL by Matthijs Dalhuijsen
# check http://www.gnu.org/gpl for details
urldecode () {
    local bf=
    local cb=
    local hi=0
    local le=0
    local x=-1
    for p in  "$@"; do
        le="${#p}"
        while (( x++ < le )); do
        case  "${p:${x}:1}" in
            "%")
                if (( hi == 0 )); then
                    (( hi++ ))  
                else
                    bf="${bf}${p:${x}:1}"
                    hi=0
                fi
                ;;
            "+")
                bf="${bf} "
                ;;
            *)
                if (( hi == 0 )); then
                    bf="${bf}${p:${x}:1}"
                fi
                if (( hi == 2 )); then
                    cb="${cb}${p:${x}:1}"
                    bf="${bf}$(echo -e "\\x${cb}")"
                    if [ "${cb}" = "0A" ] ; then
                        echo "$bf"
                        bf=
                    fi
                    hi=0
                fi
                if (( hi == 1 )); then
                    cb=${p:${x}:1}
                    (( hi++ ))
                fi
                ;;
        esac
        done
    done
    echo -n "$bf";
}

aposencode () {
  sed "s/\'/\\\'/g"
}

# Each argument NAME in answer converts to $1_NAME
ljanswer2bashvars () {
    echo "eval { local varssuccess=FAIL ;"
    eventnums=
    while read first && read second ; do
      #encoded=`echo "$second" | aposencode`
      #echo local "$1$first=\'$encoded\' ;"
      echo local "$1$first=\"$second\" ;"
      num=`echo $first | 
               awk -F"_" '{ if ($1 = "events" && $3 = "itemid") print " "$2;}'`
      eventnums="$eventnums$num"
    done
    echo "local eventnums=\"$eventnums\" ;"
    echo "local varssuccess=OK ; }"
}

# Function for authentification
# Challenges may only be used once
# Usage:
#   `authentification` || return 1
# Returns line like
#   user={username}&auth_method=challenge&auth_challenge={challenge}&auth_response={response}
# to insert it into request url
# Do not forget call checkljdir before using this
authentification () {
    # some variables
    passdesc=

    # getting challenge
    wget -O - -q "$ljuri" --post-data "mode=getchallenge" > $ljdir/getchallenge
    `cat $ljdir/getchallenge |
      ljanswer2bashvars lj_` ||
      { if [ $varssuccess = "FAILED" ] ; then
          echo "lj: incorrect answer from server" 1>&2; return 1;
        else
          echo "lj: failed in getting authentification challenge, try again" 1>&2; return 1;
        fi }
    if [ "$lj_success" = "FAIL" ] ; then
        echo "livejournal.com getchallenge: $lj_errmsg" 1>&2
        return 1
    fi

    # username
    if [ -z "$username" ] ; then
        if [ -e $ljdir/username ] ; then
            username=`head -1 $ljdir/username`
            passdesc=" for $username"
        fi
    fi
    if [ -z "$username" ] ; then
        echo -n "Livejournal username: " 1>&2 && read username
        if [ -z "$username" ] ; then
            echo "lj: you must insert your username to do anything" 1>&2
            exit 1
        fi
        passdesc=
    fi

    # password
    if [ -e $ljdir/md5password ] ; then
        md5password=`head -1 $ljdir/md5password`
    fi
    if [ -z "$md5password" ] ; then
        echo -n "Livejournal password$passdesc: " 1>&2 && read -s password && echo
        md5password=`echo -n "$password" | md5 -q`
        echo
        echo -n "Save password? (y/n): " 1>&2 && read y && echo 1>&2
        if [ "y$y" = "yy" ]; then
            echo $username > $ljdir/username
            chmod 700 $ljdir/username
            echo $md5password > $ljdir/md5password
            chmod 700 $ljdir/md5password
        fi
    fi

    # printing line
    md5response=`echo -n "$lj_challenge$md5password" | md5 -q`
    echo -n "eval { "
    echo -n "authline=\"user=$username&auth_method=challenge&auth_challenge=$lj_challenge&auth_response=$md5response\" ;"
    echo -n "username=\"$username\" ;"
    echo -n " } "
}

bool2pub () {
    if [ "0$1" = "01" ] ; then
        echo -n "A"
    else
        echo -n "I"
    fi
}

parse_time () {
    t="$1"
    if [ "${t:4:1}"  != "-" -o "${t:7:1}" != "-" -o \
         "${t:10:1}" != " " -o "${t:13:1}" != ":" ] ; then
      exit 1
    fi
    echo "${t:0:4}:${t:5:2}:${t:8:2}:${t:11:2}:${t:14:2}"
}

# converts lj values security and allowmask to short value
mk_allow_value () {
    security=$1
    allowmask=$2
    if [ "0$security" = "0" -o "0$security" = "0public" ]; then
        echo A
    elif [ "0$security" = "0private" ]; then
        echo I
    elif [ "0$security" = "0usemask" ]; then
        if [ "0$allowmask" = "01" ]; then
            echo F
        else
            echo $allowmask
        fi
    else
        echo "?$security"
    fi
}

mk_lj_allow_value () {
    letter=$1
    if [ "0$letter" = "0" -o "0$letter" = "0A" ]; then
        echo "public:"
    elif [ "0$letter" = "0I" ]; then
        echo "private:"
    elif [ "0$letter" = "0F" ]; then
        echo "usemask:1"
    elif [ "0$letter" = "0G" ]; then
        echo "usemask:$2"
    else
        exit 1
    fi
}

# Encodes http value
# Usage: echo "something" | urlencode | dosomething
urlencode () {
    # In lj api documentation said that client can leave chars a-z, A-Z and 0-9
    # without encoding
    # But I don't know how to do this with standart unix utils :)
    xxd -plain | tr -d '\n' | sed 's/\(..\)/%\1/g'
}

f_login () {
    checkljdir || return 1
    `authentification` || return 1
    journal=${journal:="$username"}

    wget -O - -q "$ljuri" --post-data "mode=login&$authline$userline&ver=1&getmoods=1&getmenus=1&getpickws=1&getpickwurls=1" > $ljdir/login

    # reading recieved lj data
    declare -A params
    while read first && read second ; do
      params["$first"]="$second"
    done < $ljdir/login

    if [ "${params["success"]}" = "FAIL" ] ; then
        echo "livejournal.com login: ${params["errmsg"]}" 1>&2
        return 1
    else
        if [ "${params["name"]}" ] ; then
            echo "Wellcome, \"${params["name"]}\"!"
        else
            echo "Hi, $username!"
        fi
        if [ "${params["message"]}" ] ; then
            echo "${params["message"]}"
        fi
    fi

    # Friends groups
    >$ljdir/$journal.frgrp.unsorted
    local num=0
    while (( num++ < ${params["frgrp_maxnum"]} )); do
      if [ "${params["frgrp_$num""_name"]}" ] ; then
          echo -e "${params["frgrp_$num""_sortorder"]}\t"\
                  "`bool2pub ${params["frgrp_$num""_public"]}`\t"\
                  "${params["frgrp_$num""_name"]}" >> $ljdir/$journal.frgrp.unsorted
      fi
    done
    sort -n $ljdir/$journal.frgrp.unsorted -o $ljdir/$journal.frgrp

    # Mood names
    >$ljdir/$journal.moods
    local n=0
    while (( n++ < ${params["mood_count"]} )); do
      echo -e "${params["mood_$n""_id"]}\t"\
              "${params["mood_$n""_name"]}" >> $ljdir/$journal.moods
    done

    # Accesses to communities
    >$ljdir/$journal.access
    local n=0
    while (( n++ < ${params["access_count"]} )); do
      echo -e "${params["access_$n"]}" >> $ljdir/$journal.access
    done

    # Menus
    # TODO: needs recursive algorithm for submenus... %)

    # User pictures
    >$ljdir/$journal.userpics
    echo -e "${params["defaultpicurl"]}\t"\
            "[default]" >> $ljdir/$journal.userpics
    local n=0
    while (( n++ < ${params["pickw_count"]} )); do
      echo -e "${params["pickwurl_$n"]}\t"\
              "${params["pickw_$n"]}" >> $ljdir/$journal.userpics
    done
}

f_send () {
	mode=$1
	shift

    userline=
    bodyfile=
    body=
    subject=
    subjectline=
    posttime=
    year=`date +%Y`
    mon=`date +%m`
    day=`date +%d`
    hour=`date +%H`
    min=`date +%M`
    props=
    allowmask=
    tags=
	itemid=
    # adult_content=[none,explicit,concepts]
    # hasscreened=[0/1]
    # opt_backdated=1 if this item shouldn't show up on people's friends lists (because it occurred in the past)
    # opt_nocomments=1 if readers can't post comments on this entry.
    # opt_noemail=1 if the poster isn't interested in receiving comments to this post by email
    # opt_preformatted=1 if post contains HTML and shouldn't be formatted
    # opt_screening=[A = All, R = Remote needed (anonymous only), F = non-Friends, N = None, else use userprop]
    # statusvis=[undef or V = visible, S = suspended]
    # useragent
    while getopts "j:b:s:t:T:m:M:l:C:O:a:AIFG:ei:" opt; do
      case $opt in
        (j)
          journal="$OPTARG"
          userline="&usejournal=$journal"
          ;;
        (b) bodyfile="$OPTARG" ;;
        (s) subject=`echo $OPTARG | urlencode`
            subjectline="&subject=$subject" ;;
        (T)
          posttime=`parse_time "$OPTARG"` || {
              echo "lj: Wrong -T argument, use this form: -T \"YYYY-MM-DD hh:mm\"" 1>&2 ;
              echo "lj: Check that argument taked in \"double quotes\"" 1>&2 ;
              echo "lj: For tags use -t parameter: -t \"tag1,tag2,tag3\"" 1>&2 ;
              exit 1 ; }
          year="${posttime:0:4}"
          mon="${posttime:5:2}"
          day="${posttime:8:2}"
          hour="${posttime:11:2}"
          min="${posttime:14:2}"
          ;;
        (t) tags="$tags,$OPTARG" ;;
        (m) current_music="$OPTARG" 
            props="$props&prop_current_music=`echo "$current_music" | urlencode`" ;;
        (M) current_mood="$OPTARG"
            props="$props&prop_current_mood=`echo "$current_mood" | urlencode`" ;;
        (O) current_moodid="$OPTARG"
            props="$props&prop_current_moodid=$current_moodid" ;;
        (l) current_location="$OPTARG"
            props="$props&prop_current_location=`echo "$current_location" | urlencode`" ;;
        # current_coords="45.2935N 123.3452W"
        (C) current_coords="$OPTARG"
            props="$props&prop_current_coords=$current_coords" ;;
        (p) picture_keyword="$OPTARG"
            props="$props&prop_picture_keyword=`echo "$picture_keyword" | urlencode`" ;;
        (e) preformatted="1"
            props="$props&prop_opt_preformatted=1" ;;
        (a) letter=${OPTARG:0:1} 
            lj_allow_value=`mk_lj_allow_value $letter ${OPTARG:1:100}` || {
                echo "lj: for all           -a A" 1>&2 ;
                echo "lj: only for friends  -a F" 1>&2 ;
                echo "lj: only for me       -a I" 1>&2 ;
                echo "lj: for friend groups -a G{groupsmask}" 1>&2 ;
                exit 1 ; }
            security=`echo "$lj_allow_value" | awk -F":" '{print $1}'`
            allowmask=`echo "$lj_allow_value" | awk -F":" '{print $2}'`
            props="$props&security=$security"
            if [ -n "$allowmask" ] ; then
              props="$props&allowmask=$allowmask"
            fi
            ;;
        (A) security="public"
            allowmask= 
            props="$props&security=public" ;;
        (F) security="usemask"
            allowmask="1"
            props="$props&security=usemask&allowmask=1" ;;
        (I) security="private"
            allowmask=
            props="$props&security=private" ;;
        (i) itemid="itemid=$OPTARG&" ;;
        # security=[public,private,usemask] + allowmask[1,*]
        (\?)
          echo "Invalid option: -$OPTARG" >&2
          exit 1
          ;;
        (:)
          echo "Option -$OPTARG requires an argument." >&2
          exit 1
          ;;
      esac
    done

    if [ "0$tags" != "0" ] ; then
        encodedtags=`echo "$tags" | urlencode`
        props="$props&prop_taglist=$encodedtags"
    fi

    if [ "0$bodyfile" = "0" ] ; then
        echo "lj: -b parameter not specified, use stdin for body" 1>&2
        bodyfile=$ljdir/postbody
        cat >$bodyfile
    fi
    body=`cat $bodyfile | urlencode`
    if [ "0$body" = "0" ] ; then
        echo $props
        echo "lj: body must not be empty"
        return 1
    fi

    checkljdir || return 1
    `authentification` || return 1
    journal=${journal:="$username"}

    # &prop_opt_preformatted=1
    wget -O - -q "$ljuri" --post-data "mode=$mode&$itemid$authline$userline$subjectline&ver=1&year=$year&mon=$mon&day=$day&hour=$hour&min=$min$props&event=$body" > $ljdir/postevent

    # reading recieved lj data
    declare -A params
    while read first && read second ; do
      params["$first"]="$second"
    done < $ljdir/postevent

    if [ "${params["success"]}" = "FAIL" ] ; then
        echo "livejournal.com login: ${params["errmsg"]}" 1>&2
        return 1
    else
        echo -n -e "${params["itemid"]}\t"
        echo "${params["url"]}" | sed "s/#/http:\/\/$journal.livejournal.com/"
    fi
}

f_post () {
	f_send postevent "$@"
}

f_edit () {
	f_send editevent "$@"
}

f_delete () {
    userline=
    itemid=
    while getopts "j:i:" opt; do
      case $opt in
        (j)
          journal="$OPTARG"
          userline="&usejournal=$journal"
          ;;
        (i)
          itemid=$OPTARG
          ;;
        (\?)
          echo "Invalid option: -$OPTARG" >&2
          exit 1
          ;;
        (:)
          echo "Option -$OPTARG requires an argument." >&2
          exit 1
          ;;
      esac
    done
    
    if [ "0$itemid" = "0" ] ; then
        echo "lj: -i {itemid} parameter required" 1>&2
        return 1
    fi

    checkljdir || return 1
    `authentification` || return 1
    journal=${journal:="$username"}

    wget -O - -q "$ljuri" --post-data "mode=editevent&$authline$userline&ver=1&itemid=$itemid" > $ljdir/editevent

    # reading recieved lj data
    declare -A params
    while read first && read second ; do
      params["$first"]="$second"
    done < $ljdir/editevent

    if [ "${params["success"]}" = "FAIL" ] ; then
        echo "livejournal.com login: ${params["errmsg"]}" 1>&2
        return 1
    fi
}

f_logout () {
    checkljdir || return 1
    rm -f $ljdir/* || true
}

# TODO: is there something standart for that?
# Usage: `getvar simplevarname varname`
# Usefull when name of variable must be calculated
# Example: `getvar id lj_events_$n""_itemid`
getvar () {
    echo "eval local $1=\"\$$2\""
}

f_dump () {
    userline=
    selecttype=lastn
    howmany=10
    reqline="selecttype=$selecttype&howmany=$howmany"
    format=
    defformat="itas"
    separator="  "
    oneitem=
    needbody=
    while getopts "j:n:b:i:d:s:f:c:" opt; do
      case $opt in
        (j) journal="$OPTARG"
            userline="&usejournal=$journal" ;;
        (n) selecttype=lastn
            howmany=$OPTARG
            reqline="selecttype=$selecttype&howmany=$howmany" ;;
        (b) beforedate="$OPTARG"
            reqline="$reqline&beforedate=`echo "$beforedate" | urlencode`" ;;
        (i) selecttype=one
            itemid=$OPTARG
            reqline="selecttype=$selecttype&itemid=$itemid"
            defformat="itatnSnb"
            oneitem=1 ;;
        (d) selecttype=day
            year=`echo $OPTARG | awk -F"-" '{print $1}'`
            month=`echo $OPTARG | awk -F"-" '{print $2}'`
            day=`echo $OPTARG | awk -F"-" '{print $3}'`
            reqline="selecttype=$selecttype&year=$year&mon=$month&day=$day"
            echo "$reqline" ;;
        (s) selecttype=syncitems
            lastsync=$OPTARG
            reqline="selecttype=$selecttype&lastsync=$lastsync" ;;
        (f) format="$OPTARG" ;;
        (c) separator="$OPTARG" ;;
        (\?)
          echo "Invalid option: -$OPTARG" >&2
          exit 1
          ;;
        (:)
          echo "Option -$OPTARG requires an argument." >&2
          exit 1
          ;;
      esac
    done

    format=${format:="$defformat"}

    if [ "`echo $format | sed 's/[-+.,ac-zA-Z0-9]//g'`" ] ; then
        needbody="1"
    fi

    checkljdir || return 1
    `authentification` || return 1
    journal=${journal:="$username"}

    wget -O - -q "$ljuri" --post-data "mode=getevents&$authline$userline&ver=1&$reqline&lineendings=pc" > $ljdir/events

    # reading recieved lj data
    declare -A params
    while read first && read second ; do
      params["$first"]="$second"
    done < $ljdir/events

    # checking for error
    if [ "${params[success]}" = "FAIL" ] ; then
        #if [ "$lj_errmsg" = "Challenge expired" ] ; then
        #    echo "lj: login time is out, relogin" 1>&2
        #else
            echo "livejournal.com getevents: ${params[errmsg]}" 1>&2
        #fi
        return 1
    fi

    # make map itemid -> (name,value), instead of propnum -> (itemid,name,value)
    declare -A props
    if [ "${params["prop_count"]}" ]; then
      local n=0
      while (( n++ < "${params["prop_count"]}" )); do
        id=${params["prop_$n""_itemid"]}
        name=${params["prop_$n""_name"]}
        props["$name$id"]="${params["prop_$n""_value"]}"
      done
    fi
    
    if [ "${params["events_count"]}" ]; then
      local n=0
      while (( n++ < "${params["events_count"]}" )); do
        id=${params["events_$n""_itemid"]}
        time=${params["events_$n""_eventtime"]}
        security=${params["events_$n""_security"]}
        allowmask=${params["events_$n""_allowmask"]}
        allow=`mk_allow_value $security $allowmask`
        subject=${params["events_$n""_subject"]}
        body=${params["events_$n""_event"]}
        rawurl=${params["events_$n""_url"]}
        url=`echo "$rawurl" | sed "s/#/http:\/\/$journal.livejournal.com/"`
        revtime=${props["revtime$id"]}
        if [ "0$revtime" = "0" ] ; then
            revtime=1
        fi
        if [ "0$needbody" = "01" ] ; then
            stamp=
            if [ -e $ljdir/$journal.$id.stamp ] ; then
                stamp=`head -1 $ljdir/$journal.$id.stamp`
            fi
            if [ "0$stamp" = "0" ] ; then
                stamp=0
            fi
            if (( revtime > stamp )) || [ ! -e $ljdir/$journal.$id.body ] ; then
                urldecode "$body"  > $ljdir/$journal.$id.body
                echo "$revtime"    > $ljdir/$journal.$id.stamp
            fi
        fi
        if [ "z$subject" = "z" ] ; then
            # 3 * 32 = 96
            summary=`echo "$body" | awk '{print substr($1, 1, 96)}'`
            subj="$summary..."
        else
            subj="$subject"
        fi
        for c in `echo "$format" | sed "s/\(.\)/\1 /g"` ; do
          case $c in
            (j) echo -n "$journal$separator" ;;
            (i) echo -n "$id$separator" ;;
            (s) echo -n "`urldecode "$subj"`$separator" ;;
            (S) echo -n "$subject$separator" ;;
            (T) echo -n "$time$separator" ;;
            (t) echo -n "${props["taglist$id"]}$separator" ;;
            (b) if [ "0$needbody" = "01" ] ; then
                    cat $ljdir/$journal.$id.body
                fi
                echo -n "$separator" ;;
            (B) echo -n "$body$separator" ;;
            (p) echo -n "${props["picture_keyword$id"]}$separator" ;;
            (u) echo -n "$url$separator" ;;
            (U) echo -n "$rawurl$separator" ;;
            (a) echo -n "$allow$separator" ;;
            (A) echo -n "${props["useragent$id"]}$separator" ;;
            (v) echo -n "${props["statusvis$id"]}$separator" ;;
            (r) echo -n "${props["revtime$id"]}$separator" ;;
            (N) echo -n "${props["revnum$id"]}$separator" ;;
            (n) echo ;;
            (,) echo -n "$separator" ;;
            (*) echo -n $c ;;
          esac
        done
        echo
      done
    fi
    chmod 600 $ljdir/*
}

f_friends () {
    userline=
    selecttype=lastn
    howmany=10
    reqline="selecttype=$selecttype&howmany=$howmany"
    format="jugts"
    defformat="un"
    separator="	"
    journal=
    count=
    while getopts "cf:s:" opt; do
      case $opt in
        (c) count=true ;;
        (f) format="$OPTARG" ;;
        (s) separator="$OPTARG" ;;
        (\?)
          echo "Invalid option: -$OPTARG" >&2
          exit 1
          ;;
        (:)
          echo "Option -$OPTARG requires an argument." >&2
          exit 1
          ;;
      esac
    done

    if [ "0$format" = "0" ] ; then
        format="$defformat"
    fi

    checkljdir || return 1
    `authentification` || return 1
    if [ "0$journal" = "0" ] ; then
        journal=$username
    fi
    wget -O - -q "$ljuri" --post-data "mode=getfriends&$authline$userline&ver=1&$reqline" > $ljdir/getfriends
    `cat $ljdir/getfriends |
      ljanswer2bashvars lj_` ||
      { if [ $varssuccess="FAILED"] ; then
          echo "lj: incorrect answer from server 1>&2"; return 1;
        else
          echo "lj: failed in sending request, try later" 1>&2; return 1;
        fi }
    if [ "$lj_success" = "FAIL" ] ; then
        if [ "$lj_errmsg" = "Challenge expired" ] ; then
            echo "lj: login time is out, relogin" 1>&2
        else
            echo "livejournal.com getfriends: $lj_errmsg" 1>&2
        fi
        return 1
    fi

    if [ "$count" = "true" ] ; then
        echo "$lj_friend_count"
        exit 0
    fi
    
    for n in `mk_range $lj_friend_count` ; do
        `getvar user        lj_friend_$n""_user`
        `getvar name        lj_friend_$n""_name`
        `getvar birthday    lj_friend_$n""_birthday`
        `getvar bg          lj_friend_$n""_bg`
        `getvar fg          lj_friend_$n""_fg`
        `getvar groupmask   lj_friend_$n""_groupmask`
        `getvar type        lj_friend_$n""_type`
        `getvar status      lj_friend_$n""_status`
        `getvar identity_display      lj_friend_$n""_identity_display`
        `getvar identity_type         lj_friend_$n""_identity_type`
        `getvar identity_value        lj_friend_$n""_identity_value`
        for c in `echo "$format" | sed "s/\(.\)/\1 /g"` ; do
          case $c in
            (j) echo -n "$user$separator" ;;
            (u) echo -n "$name$separator" ;;
            (b) echo -n "$birthday$separator" ;;
            (B) echo -n "$bg$separator" ;;
            (F) echo -n "$fg$separator" ;;
            (g) echo -n "$groupmask$separator" ;;
            (t) echo -n "$type$separator" ;;
            (s) echo -n "$status$separator" ;;
            (D) echo -n "$identity_display$separator" ;;
            (T) echo -n "$identity_type$separator" ;;
            (V) echo -n "$identity_value$separator" ;;
            (n) echo ;;
            (,) echo -n "$separator" ;;
            (*) echo -n $c ;;
          esac
        done
        echo
    done
}

f_readyup () {
    echo READYUP
}

f_checkfriends () {
    journal=
    checkljdir || return 1
    `authentification` || return 1
    if [ "0$journal" = "0" ] ; then
        journal=$username
    fi
    wget -O - -q "$ljuri" --post-data "mode=checkfriends&$authline&ver=1" > $ljdir/friendscheck
    `cat $ljdir/friendscheck |
      ljanswer2bashvars lj_` || return 1
#      { if [ $varssuccess="FAILED"] ; then
#          echo "lj: incorrect answer from server"; return 1;
#        else
#          echo "lj: failed in sending request, try later"; return 1;
#        fi }
    if [ "$lj_success" = "FAIL" ] ; then
        if [ "$lj_errmsg" = "Challenge expired" ] ; then
            echo "lj: login time is out, relogin"
        else
            echo "livejournal.com checkfriends: $lj_errmsg"
        fi
        return 1
    fi
    echo "$lj_new (check again after $lj_interval seconds)"
}

f_usage () {
    echo "Usage:   lj login"
    echo "         lj friends"
    echo "         lj readyup"
    echo "         lj logout"
    echo "         lj help {command}"
    echo "Posting: lj post -b body.txt -s \"Post Name\" -t \"tag,tag,tag\""
    echo "   (or   lj post -s \"Post Name\" -t \"tag,tag,tag\" < body.txt)"
    echo "                 -F                 - for friends only"
    echo "                 -m \"current music\" - for current music field"
    echo "                 -M \"current mood\"  - for current mood field"
}

f_help () {
    case $1 in
      (login)
            exit 0 ;;
      (logout)
            exit 0 ;;
      (dump)
            echo "lj dump -n count [-b yyyy-mm-dd hh:mm:ss] [options]"
            echo "    prints count last posts, not older than date in -b"
            echo "lj dump -i itemid [options]"
            echo "    prints only one post"
            echo "lj dump -d year month day [options]"
            echo "    prints posts for specified day"
            echo "lj dump -s yyyy-mm-dd hh:mm:ss [options]"
            echo "    prints updates after specified date"
            echo "lj dump [options]"
            echo "    works like: lj dump -n 10"
            echo "options:"
            echo "    -u {journal} print posts for another journal"
            exit 0 ;;
      (post)
            echo "    -e   Use this flag if post contains HTML and shouldn't be formatted"
            echo "         You may use <lj-raw> tag instead of this flag"
            exit 0 ;;
      (readyup)
            exit 0 ;;
      (help)
            exit 0 ;;
      (usage)
            f_usage
            exit 0 ;;
       (*)
            echo "Unknown command $1, use"
            echo "       lj usage"
            echo "for getting commands list"
            exit 0 ;;
    esac
}

setuser () {
    username=visualdoj
}

p () {
    setuser
    echo $username
}

case $1 in
  (login|logout|dump|post|readyup|usage|help|checkfriends|friends|post|delete|edit)
        method=$1
        shift
        f_$method "$@" || exit 1
        exit 0 ;;
  (include) return 0 ;;
  (debug)
        shift
        func=$1
        shift
        $func "$@"
        exit 0 ;;
esac

f_usage
